package com.one.blocks.mvc.controller;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.one.blocks.common.request.PageRequest;
import com.one.blocks.common.response.ResponseHelper;
import com.one.blocks.common.response.WebPageResponse;
import com.one.blocks.common.response.WebResponse;
import com.one.blocks.mvc.convert.BaseConvert;
import com.one.blocks.mvc.domain.Id;
import com.one.blocks.mvc.enums.MvcResponseEnum;
import com.one.blocks.mvc.manager.BaseManager;

import java.io.Serializable;
import java.util.List;
import java.util.Set;

/**
 * @author linfuxin Created on 2022-02-14 11:22:47
 */
public abstract class BaseController<Manager extends BaseManager<T>, Convert extends BaseConvert<T, V, Q>, T extends Id<? extends Serializable>, V extends Id<? extends Serializable>, Q> {

    protected final Manager manager;
    protected final Convert convert;

    public BaseController(Manager manager, Convert convert) {
        this.manager = manager;
        this.convert = convert;
    }

    public WebResponse<V> generalGet(Integer id) {
        return ResponseHelper.success(convert.entityToVo(manager.get(id)));
    }

    public WebResponse<List<V>> generalGetIds(Set<Integer> ids) {
        return ResponseHelper.success(convert.entityToVoList(manager.getByIds(ids)));
    }

    public WebPageResponse<V> generalPage(PageRequest request, Q query) {
        T entityParam = convert.queryToEntity(query);
        Page<T> page = PageHelper.startPage(request.getPageNum(), request.getPageSize(), request.isSearchCount())
                .doSelectPage(() -> manager.find(entityParam));
        return ResponseHelper.successPage(page, convert.entityToVoList(page.getResult()));
    }

    public WebResponse<Serializable> generalInsert(V v) {
        T dataToInsert = convert.voToEntityIgnoreId(v);
        manager.insert(dataToInsert);
        return ResponseHelper.success(dataToInsert.getId());
    }

//    public WebResponse<Void> generalUpdate(V v) {
//        manager.updateById(convert.voToEntity(v));
//        return ResponseHelper.success();
//    }

    public WebResponse<Void> generalUpdate(V v) {
        T dataToUpdate = manager.get(v.getId());
        if (dataToUpdate == null) {
            return ResponseHelper.fail(MvcResponseEnum.DATA_NOT_FOUND);
        }
        convert.voToEntityOverride(v, dataToUpdate);
        manager.updateById(dataToUpdate);
        return ResponseHelper.success();
    }

    public WebResponse<Void> generalUpdateSelective(V v) {
        manager.updateSelectiveById(convert.voToEntity(v));
        return ResponseHelper.success();
    }

    public WebResponse<Void> generalDelete(Integer id) {
        manager.delete(id);
        return ResponseHelper.success();
    }

    public WebResponse<Void> generalDeleteByIds(Set<Integer> ids) {
        if (ids.size() == 1) {
            return generalDelete(ids.iterator().next());
        }
        manager.deleteByIds(ids);
        return ResponseHelper.success();
    }
}